/*****************************************************************************
* FILE: 02-thread.c
* DESCRIPTION:
*   A "hello world" Pthreads program that demonstrates a safe (correct)
*   way to pass thread arguments at thread creation. Also shows how to
*   pass multiple arguments to the threaded function.
* AUTHOR: Blaise Barney, modified by J. Franco (15 Sep 2012)
* LAST REVISED: 01/30/09
******************************************************************************
  pthread.h should be first otherwise compile with -D_THREAD_SAFE 
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#define NUM_THREADS     8

typedef struct {
   char *message;
   int id;
} Data;

char *messages[NUM_THREADS];

void *PrintHello(void *data) {
   int taskid = ((Data*)data)->id;

   sleep(8-taskid);
   printf("Thread %d: %s\n", taskid, ((Data*)data)->message);
   free(data);
   pthread_exit(NULL);
}

int main(int argc, char *argv[]) {
   pthread_t threads[NUM_THREADS];
   int rc, t;
   Data *d;

   messages[0] = "English: Hello World!";
   messages[1] = "French: Bonjour, le monde!";
   messages[2] = "Spanish: Hola al mundo";
   messages[3] = "Klingon: Nuq neH!";
   messages[4] = "German: Guten Tag, Welt!"; 
   messages[5] = "Russian: Zdravstvytye, mir!";
   messages[6] = "Japan: Sekai e konnichiwa!";
   messages[7] = "Latin: Orbis, te saluto!";

   for (t=0 ; t < NUM_THREADS ; t++) {
      printf("Creating thread %ld\n", t);
      d = (Data*)malloc(sizeof(Data));
      d->message = messages[t];
      d->id = t;
      rc = pthread_create(&threads[t], NULL, PrintHello, (void*)d);
      if (rc) {
	 printf("ERROR; return code from pthread_create() is %d\n", rc);
	 exit(-1);
      }
   }
   pthread_exit(NULL);
}
